"""
示例解析器 - 为特定网站提供自定义解析逻辑
"""

from bs4 import BeautifulSoup
from crawler.parser import BaseParser

class ExampleComParser(BaseParser):
    """
    example.com网站的自定义解析器
    
    这个解析器演示了如何为特定网站编写自定义解析逻辑
    """
    
    def __init__(self):
        """初始化解析器"""
        super().__init__()
        # 指定支持的域名
        self.domains = ["example.com"]
    
    def parse(self, html, url):
        """
        解析HTML内容
        
        参数:
            html: 请求响应对象
            url: 源URL
        
        返回:
            字典: 提取的结构化数据
        """
        # 使用BeautifulSoup解析HTML
        soup = BeautifulSoup(html.text, 'lxml')
        
        # 提取数据
        result = {
            # 提取标题
            "title": self._get_title(soup),
            
            # 提取正文内容
            "content": self._get_content(soup),
            
            # 提取作者信息
            "author": self._get_author(soup),
            
            # 提取发布日期
            "publish_date": self._get_publish_date(soup),
            
            # 提取标签
            "tags": self._get_tags(soup)
        }
        
        return result
    
    def _get_title(self, soup):
        """提取标题"""
        # 首先尝试获取文章标题
        title_elem = soup.select_one('h1.article-title')
        if title_elem:
            return title_elem.get_text(strip=True)
        
        # 如果没有找到文章标题，尝试页面标题
        title_elem = soup.title
        if title_elem:
            return title_elem.get_text(strip=True)
        
        return ""
    
    def _get_content(self, soup):
        """提取正文内容"""
        # 尝试找到文章内容区域
        content_elem = soup.select_one('div.article-content')
        if content_elem:
            # 提取所有段落文本并合并
            paragraphs = content_elem.select('p')
            if paragraphs:
                return "\n\n".join([p.get_text(strip=True) for p in paragraphs])
            
            # 如果没有找到段落标签，直接获取文本
            return content_elem.get_text(strip=True)
        
        return ""
    
    def _get_author(self, soup):
        """提取作者信息"""
        # 尝试不同的选择器
        selectors = [
            'span.author',
            'a.author-link',
            'div.author-info span.name'
        ]
        
        for selector in selectors:
            author_elem = soup.select_one(selector)
            if author_elem:
                return author_elem.get_text(strip=True)
        
        return ""
    
    def _get_publish_date(self, soup):
        """提取发布日期"""
        # 尝试从时间标签获取
        date_elem = soup.select_one('time.publish-date')
        if date_elem and date_elem.has_attr('datetime'):
            return date_elem['datetime']
        
        # 尝试从其他元素获取
        date_elem = soup.select_one('span.date')
        if date_elem:
            return date_elem.get_text(strip=True)
        
        return ""
    
    def _get_tags(self, soup):
        """提取标签"""
        tags_elems = soup.select('ul.tags li')
        if tags_elems:
            return [tag.get_text(strip=True) for tag in tags_elems]
        
        # 尝试其他标签格式
        tags_elems = soup.select('div.tags a')
        if tags_elems:
            return [tag.get_text(strip=True) for tag in tags_elems]
        
        return []


class NewsExampleOrgParser(BaseParser):
    """
    news.example.org网站的自定义解析器
    
    这个解析器演示了另一种解析方式
    """
    
    def __init__(self):
        """初始化解析器"""
        super().__init__()
        # 指定支持的域名
        self.domains = ["news.example.org"]
    
    def parse(self, html, url):
        """
        解析HTML内容
        
        参数:
            html: 请求响应对象
            url: 源URL
        
        返回:
            字典: 提取的结构化数据
        """
        # 使用BeautifulSoup解析HTML
        soup = BeautifulSoup(html.text, 'lxml')
        
        # 提取数据
        result = {
            "headline": self._extract_text(soup, 'h1.headline'),
            "subheadline": self._extract_text(soup, 'h2.subheadline'),
            "summary": self._extract_text(soup, 'div.article-summary'),
            "content": self._extract_article_content(soup),
            "author": self._extract_text(soup, 'div.author-info span.name'),
            "publish_date": self._extract_date(soup),
            "category": self._extract_text(soup, 'span.category'),
            "image_url": self._extract_image_url(soup)
        }
        
        return result
    
    def _extract_text(self, soup, selector):
        """提取元素文本"""
        elem = soup.select_one(selector)
        return elem.get_text(strip=True) if elem else ""
    
    def _extract_article_content(self, soup):
        """提取文章内容"""
        content_div = soup.select_one('div.article-body')
        if not content_div:
            return ""
        
        # 提取所有段落
        paragraphs = content_div.select('p')
        if not paragraphs:
            return content_div.get_text(strip=True)
        
        return "\n\n".join([p.get_text(strip=True) for p in paragraphs])
    
    def _extract_date(self, soup):
        """提取日期"""
        date_elem = soup.select_one('time.publish-time')
        if date_elem and date_elem.has_attr('datetime'):
            return date_elem['datetime']
        
        return self._extract_text(soup, 'span.publish-date')
    
    def _extract_image_url(self, soup):
        """提取主图URL"""
        img = soup.select_one('div.main-image img')
        if img and img.has_attr('src'):
            return img['src']
        
        return ""
